﻿//
// Copyright (c) 2011 Canyala Innovation AB
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
// associated documentation files (the "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the Software is furnished to do so, 
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
//

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Canyala.Lagoon.Database;
using Canyala.Lagoon.Database.Internal;
using Canyala.Lagoon.Extensions;

namespace Canyala.Lagoon.Tests
{
    [TestClass]
    public class ActiveRecordTest
    {
        class PersonRecordView
        {
            public double Length { get; set; }
            public DateTime DateOfBirth { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }

        class Example
        {
            public string ExpectedResult { get; set; }
            public Expression<Predicate<PersonRecordView>> LambdaPredicate { get; set; }
        }

        static readonly string[] beatles = { "John", "Paul", "George", "Ringo" };

        Example[] examples = 
        {
            new Example 
            { 
                LambdaPredicate = person => person.Age == 2 && person.Name == "Test's",
                ExpectedResult = "SELECT [Length],[DateOfBirth],[Name],[Age] FROM [Person] WHERE [Age]=2 AND [Name]='Test''s'"
            },
            new Example 
            { 
                LambdaPredicate = person => person.Name.Contains("X"),
                ExpectedResult = "SELECT [Length],[DateOfBirth],[Name],[Age] FROM [Person] WHERE [Name] LIKE '%X%'"
            },
            new Example 
            { 
                LambdaPredicate = person => person.Name.StartsWith("X"),
                ExpectedResult = "SELECT [Length],[DateOfBirth],[Name],[Age] FROM [Person] WHERE [Name] LIKE 'X%'"
            },
            new Example 
            { 
                LambdaPredicate = person => person.Name.EndsWith("X"),
                ExpectedResult = "SELECT [Length],[DateOfBirth],[Name],[Age] FROM [Person] WHERE [Name] LIKE '%X'"
            }
            ,
            new Example 
            { 
                LambdaPredicate = person => beatles.Contains(person.Name),
                ExpectedResult = "SELECT [Length],[DateOfBirth],[Name],[Age] FROM [Person] WHERE [Name] IN ('John','Paul','George','Ringo')"
            }
        };

        [TestMethod]
        public void Given_a_lambda_predicate_When_converting_it_to_a_select_query_Then_we_should_get_expected_result()
            { examples.Do(example => Assert.AreEqual(example.ExpectedResult, Query.Select(example.LambdaPredicate))); }
    }
}
